﻿namespace ChinaUnicom.Tasks
{
    using System;
    using System.Linq;
    using ChinaUnicom.Models;
    using Avatar.Schedule;
    using Avatar;
    using System.Net;

    /// <summary>
    /// get all histories.
    /// </summary>
    public class FeeHistoriesTask : ITask
    {
        ITaskScheduler scheduler;

        FeeHistoryCollection ContextFeeHistories { get { return Context.Current.FeeHistories; } }

        DateTime start;

        int actual = 0;

        int limited;

        public FeeHistoryCollection Histories { get; private set; }

        public FeeHistoriesTask(int limited = -1)
        {
            if (limited <= 0)
            {
                limited = int.MaxValue;
            }

            this.limited = limited;
            Histories = new FeeHistoryCollection();
        }

        public void Start()
        {
            if (Started != null)
            {
                Started(this, EventArgs.Empty);
            }

            try
            {
                scheduler = SchedulerFactory.Create(SchedulerType.Serial);
                start = DateTime.Now.AddMonths(-1);
                // 3号 以后才能查询当月的账单
                if (start.Day < 3)
                {
                    start = start.AddMonths(-1);
                }
                start = start.ToMonthFirstDate();

                if (!GoNextRequest())
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("FeeHistories Completed {0:yyyyMM}", start));
                    if (Completed != null)
                    {
                        Completed(this, EventArgs.Empty);
                    }
                    return;
                }

                scheduler.Schedule(GenerateFeeHistoryTask(start.Year, start.Month));
                System.Diagnostics.Debug.WriteLine(string.Format("FeeHistories Schedule {0:yyyyMM}", start));
            }
            catch (Exception ex)
            {
                if (Failed != null)
                {
                    Failed(this, new FailedEventArgs(this, ex));
                }
            }
        }

        bool GoNextRequest()
        {
            while (ContextFeeHistories.Contains(start))
            {
                // 超出次数
                if ((++actual) >= limited)
                {
                    return false;
                }
                start = start.AddMonths(-1);
            }

            // 已经获得全部
            if (ApplicationSettings.Settings.PrimelyFeeHistoryDate >= start)
            {
                return false;
            }

            return true;
        }

        ITask GenerateFeeHistoryTask(int your, int month)
        {
            ITask task = new FeeHistoryTask(your, month);
            task.Started += OnTaskStated;
            task.Failed += OnFailed;
            task.Completed += OnTaskCompleted;

            return task;
        }

        void OnTaskStated(object sender, EventArgs e)
        {
            FeeHistoryTask task = sender as FeeHistoryTask;
        }

        void OnTaskCompleted(object sender, EventArgs e)
        {
            FeeHistoryTask task = sender as FeeHistoryTask;

            if (task.NotSupportedHistory || (++actual) >= limited)
            {
                if (Completed != null)
                {
                    Completed(this, EventArgs.Empty);
                }
                return;
            }

            ContextFeeHistories.Add(task.History);

            start = start.AddMonths(-1);
            if (!GoNextRequest())
            {
                System.Diagnostics.Debug.WriteLine(string.Format("FeeHistories Completed {0:yyyyMM}", start));
                if (Completed != null)
                {
                    Completed(this, EventArgs.Empty);
                }
                return;
            }

            scheduler.Schedule(GenerateFeeHistoryTask(start.Year, start.Month));

            if (Flashed != null)
            {
                Flashed(task, EventArgs.Empty);
            }
        }

        void OnFailed(object sender, FailedEventArgs e)
        {
            if (Failed != null)
            {
                Failed(this, e);
            }
        }

        public int Delay { get { return 50; } }

        public bool IsUnique { get { return true; } }

        public event EventHandler Completed;

        public event EventHandler Flashed;

        public event EventHandler Started;

        public event EventHandler<FailedEventArgs> Failed;
    }
}
